package org.kkhweb.checkbook;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

/**
 *
 * @author Kevin
 * @version 0.1
 *
 */
public class SimpleHTTPClient {

    // Variables
    private boolean _hasError;
    private String _errorMsg;
    private String _url;
    private String _response;
    private String _userAgent;
    private ArrayList<NameValuePair> _formData;
    private HttpClient _client;
    private HttpPost _post;
    private UrlEncodedFormEntity _entity;
    private ResponseHandler<String> _handler;

    // Constructor
    public SimpleHTTPClient() {
        this._hasError = false;
        this._errorMsg = "";
        this._userAgent = "SimpleHTTPClient";
        this._client = new DefaultHttpClient();
        this._formData = new ArrayList<NameValuePair>();
        this._handler = new ResponseHandler<String>() {

            @Override
            public String handleResponse(HttpResponse response)
                    throws ClientProtocolException, IOException {
                String data = "";
                HttpEntity entity = response.getEntity();

                if (entity != null) {
                    InputStream instream = entity.getContent();
                    try {
                        if (instream != null) {
                            Writer writer = new StringWriter();

                            char[] buffer = new char[1024];
                            try {
                                Reader reader = new BufferedReader(
                                        new InputStreamReader(instream, "UTF-8"));
                                int n;
                                while ((n = reader.read(buffer)) != -1) {
                                    writer.write(buffer, 0, n);
                                }
                            } finally {
                                instream.close();
                            }
                            data = writer.toString();
                        } else {
                            data = "";
                        }
                    } finally {
                        instream.close();
                    }
                }

                return data;
            }
        };
    }

    // Public Methods
    public void setURL(String url) {
        this._url = url;
    }

    public void setUserAgent(String agent) {
        this._userAgent = agent;
    }

    public void addFormData(String key, String value) {
        this._formData.add(new BasicNameValuePair(key, value));
    }

    public void sendRequest() {
        try {
            this._entity = new UrlEncodedFormEntity(this._formData, "UTF-8");
            this._post = new HttpPost(this._url);
            this._post.setEntity(this._entity);
            this._post.setHeader("User-Agent", this._userAgent);
            this._response = this._client.execute(this._post, this._handler);
            this._setErrorStatus(false);
        } catch (IOException ex) {
            this._setError(ex.getMessage());
            this._setErrorStatus(true);
        } catch (IllegalStateException ex) {
            this._setError(ex.getMessage());
            this._setErrorStatus(true);
        }
    }

    public String getResponse() {
        return this._response;
    }

    public boolean hasError() {
        return this._hasError;
    }

    public String getError() {
        return this._errorMsg;
    }

    // Private Methods
    private void _setError(String msg) {
        this._errorMsg = msg;
    }

    private void _setErrorStatus(boolean status) {
        this._hasError = status;
    }
}